/**
 * 
 */
package com.et114.components.ectable;

import javax.servlet.http.HttpServletRequest;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.Map;
//import java.util.HashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.extremecomponents.table.context.Context;
import org.extremecomponents.table.context.HttpServletRequestContext;
import org.extremecomponents.table.limit.Filter;
import org.extremecomponents.table.limit.Sort;
import org.extremecomponents.table.limit.FilterSet;
import org.extremecomponents.table.limit.Limit;
import org.extremecomponents.table.limit.LimitFactory;
import org.extremecomponents.table.limit.TableLimit;
import org.extremecomponents.table.limit.TableLimitFactory;
import org.extremecomponents.table.core.Preferences;
import org.extremecomponents.table.core.PreferencesConstants;
import org.extremecomponents.table.core.TableConstants;
import org.extremecomponents.table.core.TableModelUtils;
import org.extremecomponents.table.core.TableProperties;
import org.extremecomponents.table.core.TableModel;
import org.extremecomponents.table.core.TableModelImpl;
import org.extremecomponents.table.bean.Table;
import org.extremecomponents.table.bean.Export;
import org.extremecomponents.table.bean.Column;
import org.extremecomponents.table.bean.Row;


import org.springframework.util.Assert;


import com.et114.core.common.AppContext;
import com.et114.core.common.CONST;
import com.et114.core.dao.vo.BaseVO;
import com.et114.core.exception.CheckException;
import com.et114.core.utility.BeanUtils;
import com.et114.core.utility.URLEncoder;

//import org.apache.commons.beanutils.PropertyUtils;

/*
 * @author guanhw
 */
public class EXTableUtils {
	private static final long serialVersionUID = -665407369760335335L;
	protected static Log logger = LogFactory.getLog( EXTableUtils.class );

	
	public static Limit getLimit( HttpServletRequest request, String tableID ) {
		Context context = new HttpServletRequestContext( request );
		LimitFactory limitFactory = new TableLimitFactory( context, tableID );
		return new TableLimit( limitFactory );
	}
	
	public static void initLimitPage( BaseVO vo , int totalRows ,  HttpServletRequest request  ) throws  IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		if ( totalRows == 0  ) logger.warn( "::totalRows is :: 0 ") ; 
		BeanUtils.setProperty( vo , "totalRows" , String.valueOf( totalRows ) ) ;
		initLimitPage( vo , request  ) ; 
	}
	
	

	
	public static void setLimitRowAttributes(  BaseVO vo ,  HttpServletRequest request  ) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		initLimitPage( vo , request ) ; 
	}
	

	
	public static void initLimitPage( BaseVO vo , HttpServletRequest request   ) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException    {
		String totalRows = BeanUtils.getProperty( vo , "totalRows" ) ; 
		Assert.notNull( totalRows , "必须先初始化vo的totalRows属性！" ) ;
		String tableId = BeanUtils.getProperty( vo , "tableId" ) ; 
		if ( tableId == null || "".equals ( tableId ) ) {
			tableId = request.getParameter ( TableConstants.EXTREME_COMPONENTS_INSTANCE );//BeanUtils.getProperty( vo , "tableId" ) ;
		}
		Context context = new HttpServletRequestContext( request );
		LimitFactory limitFactory = new TableLimitFactory( context, tableId );
		Limit limit = new TableLimit( limitFactory );
		Preferences preferences = new TableProperties();
		preferences.init( null , TableModelUtils.getPreferencesLocation( context ) );
		String crdStr = tableId + "_" + TableConstants.CURRENT_ROWS_DISPLAYED;
		int defaultRowsDisplayed = Integer.parseInt( preferences.getPreference( PreferencesConstants.TABLE_ROWS_DISPLAYED ) );
		if ( request.getParameter( crdStr ) != null ) {
			defaultRowsDisplayed = Integer.parseInt( request.getParameter( crdStr ) );
		}
		limit.setRowAttributes( Integer.parseInt( totalRows  ) , defaultRowsDisplayed );
		request.setAttribute(  "totalRows" , new Integer( totalRows  ) );
		Sort sort = limit.getSort();
		StringBuffer sortSb = new StringBuffer();

		EctableConverts eConverts = vo.getEconverts ( ) ; 
		
		if ( sort.getProperty() != null ) {
			String pro = sort.getProperty ( ) ;
			if ( eConverts.proConvertsContainsKey ( pro ) ) {
				pro = eConverts.getProConvertValue ( pro ) ; 
			}
			sortSb.append ( pro  ).append ( " " ).append ( sort.getSortOrder ( ) );
			BeanUtils.setProperty( vo  , "sort", sortSb.toString() ) ;
		}
		
		StringBuffer filterst =  new StringBuffer ( ) ; 
		if ( limit.isFiltered ( ) ) {
			FilterSet filterSet = limit.getFilterSet();
			Filter[] filters = filterSet.getFilters();
			if ( filters != null  ) {
				for ( int i = 0 ; i < filters.length ; i ++ ) {
					Filter filter = filters[ i ] ;
					
					//
					String pro = filter.getProperty ( ) ;
					if ( eConverts.proConvertsContainsKey ( pro ) ) {
						pro = eConverts.getProConvertValue ( pro ) ; 
					}
					//
					String val = filter.getValue ( ) ;
					if ( eConverts.dicsContainsKey ( pro ) ) {
						EctableDic edic = eConverts.getDic ( pro ) ;
						if ( edic.containsShow ( val ) )  {
							val = edic.getValue ( val ) ;
						} 
					}
					
					filterst.append ( pro ) .append ( " like " ).append ( "'%" ).append ( val ).append ( "%'" ) ;
					if ( filters.length - 1 != i ) {
						filterst.append (  " AND "  ) ;
					}
				}
			}		
			BeanUtils.setProperty ( vo , "filter" , filterst.toString ( ) ) ;
		}
		
		
		int page = limit.getPage ( )  ; 
		int currentRowsDisplayed = limit.getCurrentRowsDisplayed() ; 
		
		BeanUtils.setProperty(  vo , "pageNum", String.valueOf(  page  ) ) ; 
		BeanUtils.setProperty(  vo , "pageSize", String.valueOf(  currentRowsDisplayed  ) ) ; 
		String cd = AppContext.getFrameWorkPropertiesBean().getDbType() ; 
		if ( CONST.DB_ORACLE.equalsIgnoreCase(  cd ) ) {
			if ( page < 0 ) page = 1 ; 
			if ( currentRowsDisplayed < 0 )  currentRowsDisplayed = 10 ; 
			int firstRow = currentRowsDisplayed * ( page - 1 ) ;
			int lastRow = currentRowsDisplayed * page  + 1 ;
			BeanUtils.setProperty(  vo , "firstRow" , String.valueOf ( firstRow ) ) ;
			BeanUtils.setProperty(  vo , "lastRow" , String.valueOf ( lastRow ) ) ;
		}
		else if ( CONST.DB_SQLSERVER.equalsIgnoreCase(  cd ) ) {
			BeanUtils.setProperty(  vo , "calculate" , String.valueOf( ( ( page > 1 ? page : 1  ) - 1 ) * currentRowsDisplayed ) ) ; 
		}
		else if ( CONST.DB_MYSQL.equalsIgnoreCase ( cd ) ) {
			BeanUtils.setProperty(  vo , "calculate" , String.valueOf( ( ( page > 1 ? page : 1  ) - 1 ) * currentRowsDisplayed ) ) ;
		}
		
	}
	
	/*
	 * 
	 */
	public static Limit getLimit( HttpServletRequest request  )  {
		Context context = new HttpServletRequestContext( request );
		LimitFactory limitFactory = new TableLimitFactory( context , request.getParameter ( TableConstants.EXTREME_COMPONENTS_INSTANCE ) );
		return new TableLimit( limitFactory );
	}
	
	/*
	 * 
	 */
	public static Limit getLimit( Context context , String tableId ) {
		LimitFactory limitFactory = new TableLimitFactory( context , tableId );
		return new TableLimit( limitFactory );
	}
	
	
	
	public static String getLimitPageParams( String tableId , Limit limit  ) throws  UnsupportedEncodingException { 
		StringBuffer to = new StringBuffer();
		String ec_p = String.valueOf ( limit.getPage ( ) ); 
		if ( ec_p != null && !"".equals ( ec_p ) ) {
			to.append ( "&" ).append ( tableId ).append ( Constants.PAGE_PIX ).append ( "=" ).append ( ec_p ) ;
		}
		return to.toString ( ) ;
	}
	
	public static String getLimitPageParams( HttpServletRequest request ) throws UnsupportedEncodingException  {
		String tableId = request.getParameter ( TableConstants.EXTREME_COMPONENTS_INSTANCE   ) ;
		Limit limit = getLimit( request ) ; 
		return getLimitPageParams( tableId , limit ) ;
	}	
	
	/**
	 * 
	 * @param tableId
	 * @param request
	 * @return
	 * @throws UnsupportedEncodingException 
	 * @throws Exception
	 */
	public static String getLimitParams( String tableId , Limit limit  ) throws  UnsupportedEncodingException {
		StringBuffer to = new StringBuffer();
		to.append (  getLimitPageParams( tableId , limit )  ) ; 
		if ( limit.isSorted ( ) ) {
			if ( limit.getSort ( ) != null  && limit.getSort ( ).getProperty ( ) != null ) {
				to.append ( "&" ).append ( tableId ).append ( Constants.SORT_PIX ).append ( limit.getSort ( ).getProperty ( ) ) ;
				to.append ( "=" ).append ( limit.getSort ( ).getSortOrder ( ) ) ;
			}			
		}
		
		if ( limit.isFiltered ( ) ) {
			FilterSet filterSet = limit.getFilterSet();
			Filter[] filters = filterSet.getFilters();
			if ( filters != null  ) {
				for ( int i = 0 ; i < filters.length ; i ++ ) {
					Filter filter = filters[ i ] ;
					String pro = filter.getProperty ( ) ;
					String val = filter.getValue ( ) ;
					to.append ( "&" ).append ( tableId ).append ( Constants.FILTER_PIX ).append ( pro ) .append ( "=" ).append (  URLEncoder.encode ( val ) ) ;
				}
				String _fa = tableId + Constants.FILTER_A ; 
				String fa = filterSet.getAction ( );
				to.append ( "&" ).append ( _fa ).append ( "=" ).append ( fa  ) ; 
			}			
		}
		return to.toString ( );		
	}
	
	
	/**
	 * 
	 * @param request
	 * @param form
	 * @return
	 * @throws CheckException 
	 * @throws UnsupportedEncodingException 
	 * @throws Exception
	 */
	public static String getLimitParams( HttpServletRequest request ) throws UnsupportedEncodingException  {
		String tableId = request.getParameter ( TableConstants.EXTREME_COMPONENTS_INSTANCE   ) ;
		Limit limit = getLimit( request ) ; 
		return getLimitParams( tableId , limit ) ;
	}
	
	/*
	 * 
	 */
	public static String getLimitParams( String tableId , Context context  ) throws  UnsupportedEncodingException { 
		Limit limit = getLimit( context , tableId ) ; 
		return getLimitParams( tableId , limit ) ;		
	}
		

	
	/**
	 * 
	 * @param parameterMap
	 * @param request
	 * @return
	 */
	public static TableModel getTableModel ( Map parameterMap , HttpServletRequest request ) {
		Context context = null;
		if ( parameterMap == null ) {
			context = new HttpServletRequestContext ( request );
		} else {
			context = new HttpServletRequestContext ( request , parameterMap );
		}
		TableModel model = new TableModelImpl ( context );
		return model;
	}
	
	
	/**
	 * 
	 * @param model
	 * @param table
	 * @param export
	 * @param row
	 * @param cols
	 */
	public static void initTableModel( TableModel model , Table table , Export export , Row row , java.util.Collection  cols  ) {
		Assert.notNull( model , "model is null！" ) ;
		Assert.notNull( table , "table is null！" ) ;
		Assert.notNull( row , "row is null！" ) ;
		Assert.notNull( cols , "cols is null！" ) ;
		model.addTable ( table ) ;
		model.addExport ( export ) ;
		model.addRow ( row ) ;
		for ( Iterator iter = cols.iterator(); iter.hasNext(); ) { 
			Object obj = iter.next ( );
			Assert.isInstanceOf( Column.class , obj , "!!" ) ;
			Column col = ( Column ) obj ; 
			model.addColumn ( col ) ;
		}
	}
}
